//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using DotNetNuke.ComponentModel;
namespace DotNetNuke.Services.Scheduling.DNNScheduling
{
	public class DNNScheduler : Services.Scheduling.SchedulingProvider
	{
		public DNNScheduler()
		{
			if (DataProvider.Instance() == null) {
				DataProvider objProvider = null;
				string defaultprovider = DotNetNuke.Data.DataProvider.Instance().DefaultProviderName;
				string dataProviderNamespace = "DotNetNuke.Services.Scheduling.DNNScheduling";
				if (defaultprovider == "SqlDataProvider") {
					objProvider = new SqlDataProvider();
				} else {
					string providerType = dataProviderNamespace + "." + defaultprovider;
					objProvider = (DataProvider)Framework.Reflection.CreateObject(providerType, providerType, true);
				}
				ComponentFactory.RegisterComponentInstance<DataProvider>(objProvider);
			}
		}
		private bool CanRunOnThisServer(string Servers)
		{
			string lwrServers = "";
			if (lwrServers != null) {
				lwrServers = Servers.ToLower();
			}
			if (String.IsNullOrEmpty(lwrServers) || lwrServers.Contains(Common.Globals.ServerName.ToLower())) {
				return true;
			} else {
				return false;
			}
		}
		public override int AddSchedule(ScheduleItem objScheduleItem)
		{
			Scheduler.CoreScheduler.RemoveFromScheduleQueue(objScheduleItem);
			objScheduleItem.ScheduleID = SchedulingController.AddSchedule(objScheduleItem.TypeFullName, objScheduleItem.TimeLapse, objScheduleItem.TimeLapseMeasurement, objScheduleItem.RetryTimeLapse, objScheduleItem.RetryTimeLapseMeasurement, objScheduleItem.RetainHistoryNum, objScheduleItem.AttachToEvent, objScheduleItem.CatchUpEnabled, objScheduleItem.Enabled, objScheduleItem.ObjectDependencies,
			objScheduleItem.Servers, objScheduleItem.FriendlyName);
			RunScheduleItemNow(objScheduleItem);
			return objScheduleItem.ScheduleID;
		}
		public override void AddScheduleItemSetting(int ScheduleID, string Name, string Value)
		{
			SchedulingController.AddScheduleItemSetting(ScheduleID, Name, Value);
		}
		public override void DeleteSchedule(ScheduleItem objScheduleItem)
		{
			SchedulingController.DeleteSchedule(objScheduleItem.ScheduleID);
			Scheduler.CoreScheduler.RemoveFromScheduleQueue(objScheduleItem);
			DotNetNuke.Common.Utilities.DataCache.RemoveCache("ScheduleLastPolled");
		}
		public override void ExecuteTasks()
		{
			if (Enabled) {
				Scheduler.CoreScheduler s = new Scheduler.CoreScheduler(Debug, MaxThreads);
				Scheduler.CoreScheduler.KeepRunning = true;
				Scheduler.CoreScheduler.KeepThreadAlive = false;
				Scheduler.CoreScheduler.Start();
			}
		}
		public override int GetActiveThreadCount()
		{
			return SchedulingController.GetActiveThreadCount();
		}
		public override int GetFreeThreadCount()
		{
			return SchedulingController.GetFreeThreadCount();
		}
		public override int GetMaxThreadCount()
		{
			return SchedulingController.GetMaxThreadCount();
		}
		public override ScheduleItem GetNextScheduledTask(string Server)
		{
			return SchedulingController.GetNextScheduledTask(Server);
		}
		public override ArrayList GetSchedule()
		{
			return new ArrayList(SchedulingController.GetSchedule().ToArray());
		}
		public override ArrayList GetSchedule(string Server)
		{
			return new ArrayList(SchedulingController.GetSchedule(Server).ToArray());
		}
		public override ScheduleItem GetSchedule(int ScheduleID)
		{
			return SchedulingController.GetSchedule(ScheduleID);
		}
		public override ScheduleItem GetSchedule(string TypeFullName, string Server)
		{
			return SchedulingController.GetSchedule(TypeFullName, Server);
		}
		public override ArrayList GetScheduleHistory(int ScheduleID)
		{
			return new ArrayList(SchedulingController.GetScheduleHistory(ScheduleID).ToArray());
		}
		public override Hashtable GetScheduleItemSettings(int ScheduleID)
		{
			return SchedulingController.GetScheduleItemSettings(ScheduleID);
		}
		public override IList<ScheduleItem> GetScheduleProcessing()
		{
			return SchedulingController.GetScheduleProcessing();
		}
		public override IList<ScheduleItem> GetScheduleQueue()
		{
			return SchedulingController.GetScheduleQueue();
		}
		public override ScheduleStatus GetScheduleStatus()
		{
			return SchedulingController.GetScheduleStatus();
		}
		public override void Halt(string SourceOfHalt)
		{
			Scheduler.CoreScheduler s = new Scheduler.CoreScheduler(Debug, MaxThreads);
			Scheduler.CoreScheduler.Halt(SourceOfHalt);
			Scheduler.CoreScheduler.KeepRunning = false;
		}
		public override void PurgeScheduleHistory()
		{
			Scheduler.CoreScheduler s = new Scheduler.CoreScheduler(MaxThreads);
			Scheduler.CoreScheduler.PurgeScheduleHistory();
		}
		public override void ReStart(string SourceOfRestart)
		{
			Halt(SourceOfRestart);
			StartAndWaitForResponse();
		}
		public override void RunEventSchedule(Scheduling.EventName objEventName)
		{
			if (Enabled) {
				Scheduler.CoreScheduler s = new Scheduler.CoreScheduler(Debug, MaxThreads);
				Scheduler.CoreScheduler.RunEventSchedule(objEventName);
			}
		}
		public override void RunScheduleItemNow(ScheduleItem objScheduleItem)
		{
			Scheduler.CoreScheduler.RemoveFromScheduleQueue(objScheduleItem);
			ScheduleHistoryItem objScheduleHistoryItem = new ScheduleHistoryItem(objScheduleItem);
			objScheduleHistoryItem.NextStart = DateTime.Now;
			if (objScheduleHistoryItem.TimeLapse != DotNetNuke.Common.Utilities.Null.NullInteger && objScheduleHistoryItem.TimeLapseMeasurement != DotNetNuke.Common.Utilities.Null.NullString && objScheduleHistoryItem.Enabled && CanRunOnThisServer(objScheduleItem.Servers)) {
				objScheduleHistoryItem.ScheduleSource = ScheduleSource.STARTED_FROM_SCHEDULE_CHANGE;
				Scheduler.CoreScheduler.AddToScheduleQueue(objScheduleHistoryItem);
			}
			DotNetNuke.Common.Utilities.DataCache.RemoveCache("ScheduleLastPolled");
		}
		public override Dictionary<string, string> Settings {
			get { return DotNetNuke.ComponentModel.ComponentFactory.GetComponentSettings<DNNScheduler>() as Dictionary<string, string>; }
		}
		public override void Start()
		{
			if (Enabled) {
				Scheduler.CoreScheduler s = new Scheduler.CoreScheduler(Debug, MaxThreads);
				Scheduler.CoreScheduler.KeepRunning = true;
				Scheduler.CoreScheduler.KeepThreadAlive = true;
				Scheduler.CoreScheduler.Start();
			}
		}
		public override void StartAndWaitForResponse()
		{
			if (Enabled) {
				Thread newThread = new Thread(Start);
				newThread.IsBackground = true;
				newThread.Start();
				int i;
				for (i = 0; i <= 30; i++) {
					if (GetScheduleStatus() != ScheduleStatus.STOPPED)
						return;
					Thread.Sleep(1000);
				}
			}
		}
		public override void UpdateSchedule(ScheduleItem objScheduleItem)
		{
			Scheduler.CoreScheduler.RemoveFromScheduleQueue(objScheduleItem);
			SchedulingController.UpdateSchedule(objScheduleItem.ScheduleID, objScheduleItem.TypeFullName, objScheduleItem.TimeLapse, objScheduleItem.TimeLapseMeasurement, objScheduleItem.RetryTimeLapse, objScheduleItem.RetryTimeLapseMeasurement, objScheduleItem.RetainHistoryNum, objScheduleItem.AttachToEvent, objScheduleItem.CatchUpEnabled, objScheduleItem.Enabled,
			objScheduleItem.ObjectDependencies, objScheduleItem.Servers, objScheduleItem.FriendlyName);
			RunScheduleItemNow(objScheduleItem);
		}
	}
}
